package com.bsidesoft.adr;

import org.xml.sax.*;

import android.graphics.*;
import android.text.*;
import android.text.Html.TagHandler;
import android.text.style.*;
import android.widget.*;

final class bsHtmlTagHandler{
	
	final static protected int TAG_STYLE = 0;
	
	final static protected int ATTR_SIZE_PX = 0;
	final static protected int ATTR_SIZE_DIP = 1;
	final static protected int ATTR_COLOR = 2;
	final static protected int ATTR_BGCOLOR = 3;
	final static protected int ATTR_STRIKE = 4;
	final static protected int ATTR_UNDERLINE = 5;
	final static protected int ATTR_BOLD = 6;
	final static protected int ATTR_ITALIC = 7;
	final static protected int ATTR_BOLDITALIC = 8;
	final static protected int ATTR_FONT = 9;
	
	static protected HashMap<String, Integer> _tags = new HashMap<String, Integer>();
	static protected HashMap<String, Integer> _attrs = new HashMap<String, Integer>();
	
	static private TagHandler tagHandler = new TagHandler() {
		@Override
		public void handleTag( boolean $isOpen, String $tag, Editable $out, XMLReader $xml ){
			if( $tag.indexOf( bsStr.TAGSEP ) == -1 ) return;
			
			int len = $out.length();			
			String[] data = bsStr.tagData( $tag );
			
			if( $isOpen ){
				$out.setSpan( data, len, len, Spannable.SPAN_MARK_MARK );
				return;
			}
			String[][] temp = $out.getSpans( 0, len, String[].class );
			if( temp.length == 0) return;
			
			String[] target = null;
			for( int i = temp.length - 1 ; i > -1 ; --i ){
				if( $out.getSpanFlags( temp[i] ) == Spannable.SPAN_MARK_MARK ){
					target = temp[i];
					break;
				}
			}
			if( target == null) return;
			
			int from = $out.getSpanStart( target );
			$out.removeSpan( target );
			if( from == len ) return;
			
			switch( _tags.get( target[0] ) ){
			case TAG_STYLE:
				for( int k = 1, l = target.length ; k < l ; ){
					int key = _attrs.get( target[k++] );
					CharacterStyle style = null;
					switch( key ){
					case ATTR_STRIKE: style = new StrikethroughSpan(); break;
					case ATTR_UNDERLINE: style = new UnderlineSpan(); break;
					case ATTR_BOLD: style = new StyleSpan( Typeface.BOLD ); break;
					case ATTR_ITALIC: style = new StyleSpan( Typeface.ITALIC ); break;
					case ATTR_BOLDITALIC: style = new StyleSpan( Typeface.BOLD_ITALIC ); break;
					default:
						String val = target[k++];
						switch( key ){
						case ATTR_SIZE_PX: style = new AbsoluteSizeSpan( Integer.parseInt( val ) ); break;
						case ATTR_SIZE_DIP: style = new AbsoluteSizeSpan( Integer.parseInt( val ), true ); break;
						case ATTR_COLOR: style = new ForegroundColorSpan( Color.parseColor( "#" + val ) ); break;
						case ATTR_BGCOLOR: style = new BackgroundColorSpan( Color.parseColor( "#" + val ) ); break;
						case ATTR_FONT: style = new TypefaceSpan( val ); break;
						}
					}
					$out.setSpan( style, from, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
				}
			}
		}
	};
	
	static void onInit(){
		_tags.put( "style", TAG_STYLE );
		
		_attrs.put( "px", ATTR_SIZE_PX );
		_attrs.put( "dp", ATTR_SIZE_DIP );
		_attrs.put( "co", ATTR_COLOR );
		_attrs.put( "bg", ATTR_BGCOLOR );
		_attrs.put( "sk", ATTR_STRIKE );
		_attrs.put( "un", ATTR_UNDERLINE );
		_attrs.put( "b", ATTR_BOLD );
		_attrs.put( "i", ATTR_ITALIC );
		_attrs.put( "bi", ATTR_BOLDITALIC );
		_attrs.put( "fo", ATTR_FONT );
	}
	
	static void setHtml( TextView $text, String $html ){
		$text.setText( Html.fromHtml( $html, null, tagHandler ) );
	}
	
	static void test( Activity $act ){
		setHtml( new TextView( $act ), 
			"test<br><style_dp_30_co_ff0000_bg_ffffff_b>style - size 30dip, color #ff0000, bgcolor #ffffff and bold</style_dp_30_co_ff0000_bg_ffffff_b>"
		);
	}
}